#include "edges.h"

Edges::Edges() {
	// nothing needs to be set up
}

Edges::~Edges() {
	std::vector<std::vector<std::pair<int, int> > >().swap(e); // swap v with an empty vector
}

// takes a vector of edges (vertex pairs) and returns true if that combination of edges already exists in e. (false otherwise)
bool Edges::contains(std::vector<std::pair<int, int> > edges) {

	for(unsigned int i = 0; i < e.size(); i++) { // loop through each vector of edge pairs
		int count = 0; // count of edges that match

		for(unsigned int j = 0; j < edges.size(); j++) { // loop through each element of the vector to test
			for(unsigned int k = 0; k < edges.size(); k++) { // check each of those elements against each existing element
				if(e.at(i).at(k) == edges.at(j) || (e.at(i).at(k).first == edges.at(j).second && e.at(i).at(k).second == edges.at(j).first))
					count++;
			}
		}
		if(count == edges.size()) // if every edge matches, the combination already exists so return true
			return true;
	}

	return false;
}

void Edges::add(std::vector<std::pair<int, int> > edges) {
	if(!contains(edges)) {
		e.push_back(edges);
	}
}

int Edges::getNumCombinations() {
	return e.size();
}

int Edges::printCombinations() {
	std::cout << "All Mapped Combinations:" << std::endl;
	for(unsigned int i = 0; i < e.size(); i++) {
		for(unsigned int j = 0; j < e.at(i).size(); j++) {
			//std::cout << v.at(i).at(j) << " ";
			std::cout << e.at(i).at(j).first << " <-> " << e.at(i).at(j).second << ", ";
		}
		std::cout << std::endl;
	}

	return e.size();
}

int Edges::printCombinations(std::vector<std::pair<int, std::string> > nameRelations) {
	//std::cout << "All Mapped Combinations:" << std::endl;
	for(unsigned int i = 0; i < e.size(); i++) {
		for(unsigned int j = 0; j < e.at(i).size(); j++) {
			// I can do this direct mapping (no searching) because of how the nameRelations vector was built (sorted by int inherintly)
			//std::cout << nameRelations.at(v.at(i).at(j)).second << " ";
			std::cout << nameRelations.at(e.at(i).at(j).first).second << " <-> " << nameRelations.at(e.at(i).at(j).second).second << ", ";
		}
		std::cout << std::endl;
	}

	return e.size();
}

int Edges::printCombinations(std::vector<std::pair<int, std::string> > nameRelations, std::string fileName) {
	//std::cout << "All Mapped Combinations:" << std::endl;

	std::ofstream fileOut(fileName.c_str(), std::ofstream::out);

	for(unsigned int i = 0; i < e.size(); i++) {
		for(unsigned int j = 0; j < e.at(i).size(); j++) {
			// I can do this direct mapping (no searching) because of how the nameRelations vector was built (sorted by int inherintly)
			//fileOut << nameRelations.at(v.at(i).at(j)).second << " ";
			fileOut << nameRelations.at(e.at(i).at(j).first).second << " <--> " << nameRelations.at(e.at(i).at(j).second).second << ", ";
		}
		fileOut << std::endl;
	}
	fileOut.flush();
	fileOut.close();
	//std::cout << "Output subgraph mappings written to disk." << std::endl;

	return e.size();
}
